<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 1.立即执行函数
        (function () {
            console.log("我是1");
        })();
        !function () {
            console.log("我是2");
        }();

        // 立即执行函数传参
        (function (num) {
            console.log("我是1");
            console.log(num);
        })(100);
        !function (num) {
            console.log("我是3");
            console.log(num);
        }(300);


        // 2.递归函数
        function sum(m) {
            if (m <= 0) {
                return; // 出口 - 停止递归(防止代码往下执行)
            }
            console.log(m);
            sum(--m);
        }
        sum(5);


        // 3.高阶函数
        // 定义高阶函数myTimeout, 参数是一个函数体
        function myTimeout(fn) {
            fn();
        }
        // 调用高阶函数 - 传入参数是一个函数体
        myTimeout(function () {
            console.log("myTimeout调用 - 传入一个函数体, 函数体执行了");
        });
        // 2. 函数作为返回值 - (了解)
        function getHobby() {
            return function () {
                console.log("返回了一个函数体");
            }
        }
        var theFn = getHobby(); // 得到高阶函数内返回的function
        theFn(); // 导致内部return后的函数执行
        // 使用场景:
        // 第一种: 参数为函数体使用: 例如, 创建类似 - 数组的map方法
        function myMap(fn, arr) {
            for (var i = 0; i < arr.length; i++) {
                fn(arr[i]);
            }
        }
        myMap(function (val) {
            console.log(val);
        }, [10, 5, 3, 2]);



        // 4.回调函数
        // 语法: my是高阶函数, fn参数的值是function(){}函数体
        function my(fn) {
            fn(); // 这里调用外部传入进来的函数 - 回调外部的函数体执行 - 这个动作就叫回调函数
        }
        my(function () {
            console.log("函数执行");
        })


    </script>

</body>

</html>